package com.jhf.youke.sales.domain.service;

import com.jhf.youke.core.ddd.AbstractDomainService;
import com.jhf.youke.core.entity.PageQuery;
import com.jhf.youke.core.entity.Pagination;
import com.jhf.youke.sales.domain.converter.RecommendedConverter;
import com.jhf.youke.sales.domain.gateway.RecommendedRepository;
import com.jhf.youke.sales.domain.model.Do.RecommendedDo;
import com.jhf.youke.sales.domain.model.dto.OrderDto;
import com.jhf.youke.sales.domain.model.dto.OrderItemDto;
import com.jhf.youke.sales.domain.model.dto.ProductCommissionDto;
import com.jhf.youke.sales.domain.model.po.CommissionPo;
import com.jhf.youke.sales.domain.model.po.RecommendedPo;
import com.jhf.youke.sales.domain.model.vo.RecommendedVo;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;


/**
 * @author RHJ
 */
@Service
public class RecommendedService extends AbstractDomainService<RecommendedRepository, RecommendedDo, RecommendedVo> {


    @Resource
    RecommendedConverter recommendedConverter;

    @Override
    public boolean update(RecommendedDo entity) {
        RecommendedPo recommendedPo = recommendedConverter.do2Po(entity);
        recommendedPo.preUpdate();
        return repository.update(recommendedPo);
    }

    @Override
    public boolean updateBatch(List<RecommendedDo> doList) {
        List<RecommendedPo> poList = recommendedConverter.do2PoList(doList);
        return repository.updateBatch(poList);
    }

    @Override
    public boolean delete(RecommendedDo entity) {
        RecommendedPo recommendedPo = recommendedConverter.do2Po(entity);
        return repository.delete(recommendedPo);
    }

    @Override
    public boolean deleteBatch(List<Long> idList) {
        return repository.deleteBatch(idList);
    }

    @Override
    public boolean insert(RecommendedDo entity) {
        RecommendedPo recommendedPo = recommendedConverter.do2Po(entity);
        recommendedPo.preInsert();
        // 补充所有父类id
        RecommendedPo referrer = repository.getByUser(recommendedPo.getCompanyId(), recommendedPo.getReferrer());
        recommendedPo.setParentIds(referrer.getParentIds() + recommendedPo.getUserId() + ",");
        return repository.insert(recommendedPo);
    }

    @Override
    public boolean insertBatch(List<RecommendedDo> doList) {
        List<RecommendedPo> poList = recommendedConverter.do2PoList(doList);
        poList = RecommendedPo.getInsertListId(poList);
        return repository.insertBatch(poList);
    }

    @Override
    public Optional<RecommendedVo> findById(Long id) {
        Optional<RecommendedPo> recommendedPo =  repository.findById(id);
        RecommendedVo recommendedVo = recommendedConverter.po2Vo(recommendedPo.orElse(new RecommendedPo()));
        return Optional.ofNullable(recommendedVo);
        
    }

    @Override
    public boolean remove(Long id) {
        return repository.remove(id);
    }

    @Override
    public boolean removeBatch(List<Long> idList) {
        return repository.removeBatch(idList);
    }

    @Override
    public List<RecommendedVo> findAllMatching(RecommendedDo entity) {
        RecommendedPo recommendedPo = recommendedConverter.do2Po(entity);
        List<RecommendedPo>recommendedPoList =  repository.findAllMatching(recommendedPo);
        return recommendedConverter.po2VoList(recommendedPoList);
    }


    @Override
    public Pagination<RecommendedVo> selectPage(RecommendedDo entity){
        RecommendedPo recommendedPo = recommendedConverter.do2Po(entity);
        PageQuery<RecommendedPo> pageQuery = new PageQuery<>(recommendedPo,entity.getCurrentPage(), entity.getPageSize(), entity.getQuerySort());
        Pagination<RecommendedPo> pagination = repository.selectPage(pageQuery);
        return new Pagination<>(pagination.getPageNum(),pagination.getPageSize(),pagination.getTotalSize(),
                recommendedConverter.po2VoList(pagination.getList()));
    }


    /**
    * @Description:  查找自己以及上级的用户
    * @Param: [companyId, salesman]
    * @return: java.util.List<com.jhf.youke.sales.domain.model.po.RecommendedPo>
    * @Author: RHJ
    * @Date: 2022/10/2
    */

    public List<RecommendedPo> getParentList(Long companyId, Long salesman) {

        return  repository.getParentList(companyId, salesman);

    }

    /**
    * @Description:  创建推荐关系
    * @Param: [recommendedDo]
    * @return: void
    * @Author: RHJ
    * @Date: 2022/10/4
    */
    public void recommend(RecommendedDo recommendedDo){
        // 查询推荐关系是否存在
        RecommendedPo oldRecommendedPo = repository.getByUser(recommendedDo.getCompanyId(), recommendedDo.getUserId());
        if(oldRecommendedPo != null){
          return;
        }
        // 查询上级用户信息
        RecommendedPo parent = repository.getByUser(recommendedDo.getCompanyId(),recommendedDo.getReferrer());
        recommendedDo.setParent(parent);
        RecommendedPo recommendedPo = recommendedConverter.do2Po(recommendedDo);
        recommendedPo.preInsert();
        repository.insert(recommendedPo);

    }

    /**
    * @Description: 佣金计算
    * @Param: [recommendedPoList, commissionDtoList]
    * @return: java.util.List<com.jhf.youke.sales.domain.model.po.CommissionPo>
    * @Author: RHJ
    * @Date: 2022/10/2
    */
    public List<CommissionPo> computeCommission(OrderDto orderDto, OrderItemDto item, List<RecommendedPo> recommendedPoList,
                                                List<ProductCommissionDto> commissionDtoList){
        List<CommissionPo> commissionPoList = new ArrayList<>();

        Long propertyId1 = item.getPropertyId1();
        Long propertyId2 = item.getPropertyId2();
        Long propertyId3 = item.getPropertyId3();
        BigDecimal num = item.getNum();
        for(int i = 0; i< recommendedPoList.size(); i++) {
            RecommendedPo recommendedPo = recommendedPoList.get(i);
            Integer level = recommendedPo.getLevel();
            // 是否平级
            Boolean isSameLevel = false;
            // 获取上一级判断是否平级
            if(i > 0){
                RecommendedPo old = recommendedPoList.get(i-1);
                if(old.getLevel().equals(level)){
                    isSameLevel = true;
                }
            }

            for (ProductCommissionDto commissionDto : commissionDtoList){
                if(commissionDto.getLevel().equals(level)){
                    CommissionPo commissionPo = new CommissionPo();
                    commissionPo.setBizId(orderDto.getOrderId());
                    commissionPo.setUserId(recommendedPo.getUserId());
                    commissionPo.setUserName(recommendedPo.getUserName());
                    commissionPo.setStatus(0);
                    commissionPo.setProductReleaseId(item.getProductReleaseId());
                    commissionPo.setProductName(item.getProductName());

                   if(propertyId1 > 0 && propertyId2 >0 && propertyId3 >0){
                       if(propertyId1.equals(commissionDto.getPropertyId1()) &&
                               propertyId2.equals(commissionDto.getPropertyId2()) &&
                               propertyId3.equals(commissionDto.getPropertyId3())){
                           compute(commissionDto,commissionPoList,commissionPo,isSameLevel,num);
                           break;
                       }
                   }else if(propertyId1 > 0 && propertyId2 >0){
                       if(propertyId1.equals(commissionDto.getPropertyId1()) &&
                               propertyId2.equals(commissionDto.getPropertyId2())){

                           compute(commissionDto,commissionPoList,commissionPo,isSameLevel,num);
                           break;
                       }
                   }else if(propertyId1 > 0){
                       if(propertyId1.equals(commissionDto.getPropertyId1())){
                           compute(commissionDto,commissionPoList,commissionPo,isSameLevel,num);
                           break;
                       }
                   }else if(propertyId1 == 0 && propertyId2 ==0 && propertyId3 ==0){
                          compute(commissionDto,commissionPoList,commissionPo,isSameLevel,num);
                          break;
                   }
               }
            }
        }

        return commissionPoList;
    }

    /**
     * 佣金计算
     *
     * @param commissionDto
     * @param list          列表
     * @param commissionPo
     * @param isSameLevel
     * @param num
     * @return {@link List}<{@link CommissionPo}>
     */
    public List<CommissionPo> compute(ProductCommissionDto commissionDto, List<CommissionPo> list, CommissionPo commissionPo, Boolean isSameLevel, BigDecimal num){

        if(commissionDto.getType() == 1) {
            if (isSameLevel) {
                commissionPo.setFee(num.multiply(commissionDto.getPeersCommission()));
            } else {
                commissionPo.setFee(num.multiply(commissionDto.getCommission()));
            }
        }
        list.add(commissionPo);
        return list;
    }



}

